import requestAxios from '@/assets/js/axios.js'

let api = '/manager/user_balance_record/batch_send_raw_transaction.do';
// /manager/user_balance_record/send_raw_transaction.do

let Web3 = require("web3");
let Tx = require('ethereumjs-tx').Transaction

// 创建web3对象
let web3 = new Web3('https://mainnet.infura.io/v3/7319f54f8c414f10915b48ede5406388')
// let web3 = new Web3('https://ropsten.infura.io/v3/7319f54f8c414f10915b48ede5406388')

// 定义合约abi
// var contractAbi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_value","type":"uint256"}],"name":"burnFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"tokenSymbol","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"}];

var contractAbi = [{
    "constant": true,
    "inputs": [],
    "name": "name",
    "outputs": [{"name": "", "type": "string"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "spender", "type": "address"}, {"name": "value", "type": "uint256"}],
    "name": "approve",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "totalSupply",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": true,
    "inputs": [{"name": "value", "type": "uint256"}],
    "name": "findRewardPercent",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": true,
    "inputs": [{"name": "value", "type": "uint256"}],
    "name": "findBurnPercent",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "receivers", "type": "address[]"}, {"name": "amounts", "type": "uint256[]"}],
    "name": "multiTransfer",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "from", "type": "address"}, {"name": "to", "type": "address"}, {
        "name": "value",
        "type": "uint256"
    }],
    "name": "transferFrom",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "decimals",
    "outputs": [{"name": "", "type": "uint8"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "spender", "type": "address"}, {"name": "addedValue", "type": "uint256"}],
    "name": "increaseAllowance",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "amount", "type": "uint256"}],
    "name": "burn",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [{"name": "owner", "type": "address"}],
    "name": "balanceOf",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "account", "type": "address"}, {"name": "amount", "type": "uint256"}],
    "name": "burnFrom",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "symbol",
    "outputs": [{"name": "", "type": "string"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "spender", "type": "address"}, {"name": "subtractedValue", "type": "uint256"}],
    "name": "decreaseAllowance",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [{"name": "value", "type": "uint256"}],
    "name": "findOnePercent",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "to", "type": "address"}, {"name": "value", "type": "uint256"}],
    "name": "transfer",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "baseBurnPercent",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "basePercent",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "value", "type": "address"}],
    "name": "assignRewardAddress",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [{"name": "owner", "type": "address"}, {"name": "spender", "type": "address"}],
    "name": "allowance",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [{"name": "burnPercent", "type": "uint256"}, {"name": "rewardPercent", "type": "uint256"}],
    "name": "modifyPercent",
    "outputs": [{"name": "", "type": "bool"}],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "baseRewardPercent",
    "outputs": [{"name": "", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {"inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor"}, {
    "anonymous": false,
    "inputs": [{"indexed": true, "name": "from", "type": "address"}, {
        "indexed": true,
        "name": "to",
        "type": "address"
    }, {"indexed": false, "name": "value", "type": "uint256"}],
    "name": "Transfer",
    "type": "event"
}, {
    "anonymous": false,
    "inputs": [{"indexed": true, "name": "owner", "type": "address"}, {
        "indexed": true,
        "name": "spender",
        "type": "address"
    }, {"indexed": false, "name": "value", "type": "uint256"}],
    "name": "Approval",
    "type": "event"
}]
// 合约地址
var contractAddress = "0xD4Cdd5e54CcEddA7e9408B31759c9F9CEECbB3eC";

// 账号
var currentAccount = "0xcf07ed63199653955A7c7C94B9EE4E1Bb3D64935";

// 定义合约
var myContract = new web3.eth.Contract(contractAbi, contractAddress, {
    from: currentAccount, // default from address
    gasPrice: '1000000000' // default gas price in wei, 10 gwei in this case
});

export default {

    getETHBalance(address) {
        web3.eth.getBalance(address).then(console.log)
    },

    createAccount() {
        let object = web3.eth.accounts.create()
        console.log('obj = ', JSON.stringify(object))
    },

    async listAccount() {
        // let result = await web3.eth.getAccounts()
        // console.log('listAccount = ', result)
    },

    getTokenName() {
        myContract.methods.name().call({from: currentAccount}, function (error, result) {
            if (error) {
                // console.log('name = ', error)
            } else {
                // console.log('name = ', result)
            }
        })
    },

    getTokenSymbol() {
        myContract.methods.symbol().call({from: currentAccount}, function (error, result) {
            if (error) {
                // console.log('symbol = ', error)
            } else {
                // console.log('symbol = ', result)
            }
        })
    },

    getTokenBalance(fromAddress) {
        myContract.methods.balanceOf(fromAddress).call({from: currentAccount}, function (error, result) {
            if (error) {
                // console.log('balance = ', error)
            } else {
                // console.log('balance = ', result)
            }
        })
    },

    async getNonce(address) {
        let nonce = await web3.eth.getTransactionCount(address)
        // console.log('nonce = ' + nonce)
        return nonce
    },

    sendTx(params, callback) {

        if (params.coin == 'ETH') {
            this.sendETHTx(params, callback)
        } else if (params.coin == 'WET') {
            this.sendTokenTx(params, callback)
        }
    },

    async batchSendTx(from, array, callback) {
        // console.log('---->', from ,array)
        // let nonce = await web3.eth.getTransactionCount(from);
        let paramsArr = [];
        for (let i in array) {
            let params = array[i]
            // console.log("====>" + params)
            // params.nonce = nonce + parseInt(i);
            if (params.coin == 'ETH') {
                this.sendETHTx(params, callback)
            } else if (params.coin == 'WET') {
                let paramsData = this.sendTokenTx(params)
                // this.sendTokenTx(params).then(response => {
                //     console.log('response == ',response)
                //     paramsData = response;
                // })
                paramsArr.push({recordId: params.id, data: paramsData})
            }
        }

        requestAxios.requestCMS('post', api, {
            array: JSON.stringify(paramsArr)
        }, (data) => {
            // console.log(123456, data);
            callback(data)
        })

    },

    sendTokenTx(params, callback) {
        // console.log('params===' ,params)
        // callback("ox")
        let {privateKey, from, toAddress, count, gasLimit} = params
        count = count * 100
        // console.log('count = ', count)
        // return
        // let nonce = params.nonce || web3.eth.getTransactionCount(from)
        let nonce = params.nonce;
        // console.log('nonce = ', nonce)
        // let gasPrice = await web3.eth.getGasPrice()
        let gasPrice = 1000000000
        // // console.log('gasPrice = ', gasPrice)
        // gasPrice = gasPrice / 1000000000
        gasPrice = gasPrice * (params.gasPrice || 1)
        // console.log('gasPrice = ' + gasPrice)
        var txData = {
            nonce: web3.utils.toHex(nonce),
            gasLimit: web3.utils.toHex(gasLimit),
            gasPrice: gasPrice,
            from: from,
            // 注意这里是代币合约地址
            to: contractAddress,
            // 调用合约转账value这里留空
            value: '0x00',
            // data的组成，由：0x + 要调用的合约方法的function signature + 要传递的方法参数，每个参数都为64位(对transfer来说，第一个是接收人的地址去掉0x，第二个是代币数量的16进制表示，去掉前面0x，然后补齐为64位)
            data: '0x' + 'a9059cbb' + this.addPreZero(toAddress.substr(2)) + this.addPreZero(web3.utils.toHex(count).substr(2))
        }
        // console.log('WET txData = ', JSON.stringify(txData))
        // return
        var tx = new Tx(txData)
        const key = new Buffer(privateKey.substr(2), 'hex')
        tx.sign(key)
        let serializedTx = tx.serialize().toString('hex')

        return '0x' + serializedTx;

        // web3.eth.sendSignedTransaction('0x' + serializedTx, (error, hash) => {
        //     if(!error) {
        //         // console.log('hash = ' + hash)
        //         if(callback) {
        //             callback({params: params, hash: hash})
        //         }
        //         // alert('hash = ' + hash)
        //     }else {
        //         // console.log('error = ', error)
        //         if(callback) {
        //             callback({params: params})
        //         }
        //     }
        // })
    },

    // async sendTx() {
    //     this.sendETHTx(account.privateKey, account.address, account_2.address, 100000, 1000000)
    // },

    async sendETHTx(params, callback) {
        let {privateKey, from, to, count, gasLimit} = params
        let nonce = params.nonce || await web3.eth.getTransactionCount(from)
        // console.log('nonce = ', nonce)
        let gasPrice = await web3.eth.getGasPrice()
        // console.log('gasPrice = ', gasPrice)
        // gasPrice = gasPrice / 1000000000'
        // let gasPrice = 1000000000
        gasPrice = gasPrice * (params.gasPrice || 1)
        console.log('gasPrice = ' + gasPrice)
        var txData = {
            nonce: web3.utils.toHex(nonce++),
            gasLimit: web3.utils.toHex(gasLimit),
            gasPrice: web3.utils.toHex(gasPrice),
            from: from,
            to: to,
            value: web3.utils.toHex(count * 1e18),
            data: ''
        }
        // console.log('ETH txData = ', JSON.stringify(txData))
        var tx = new Tx(txData)
        const key = new Buffer(privateKey.substr(2), 'hex')
        tx.sign(key)
        let serializedTx = tx.serialize().toString('hex')
        web3.eth.sendSignedTransaction('0x' + serializedTx, (error, hash) => {
            if (!error) {
                console.log('hash = ' + hash)
                if (callback) {
                    callback({params: params, hash: hash})
                }
            } else {
                console.log('error = ', error)
                if (callback) {
                    callback({params: params})
                }
            }
        })
    },

    // 补齐64位，不够前面用0补齐
    addPreZero(num) {
        var t = (num + '').length,
            s = '';
        for (var i = 0; i < 64 - t; i++) {
            s += '0';
        }
        return s + num;
    },

    getTx() {
        var addr = "0xbfb2e296d9cf3e593e79981235aed29ab9984c0f"
        var filter = web3.eth.filter({fromBlock: 0, toBlock: 'latest', address: addr});
        filter.get(function (err, transactions) {
            transactions.forEach(function (tx) {
                var txInfo = web3.eth.getTransaction(tx.transactionHash);
                //这时可以将交易信息txInfo存入数据库
            });
        });
    }
}
